<?php

declare(strict_types=1);

namespace App\Controller\Home\Drp;

use App\Controller\AbstractController;
use App\Model\Bill;
use App\Model\Device;
use App\Model\DistributorDevice;
use App\Model\Distributors;
use App\Model\Normal;
use App\Model\Order;
use App\Model\Station;
use Carbon\Carbon;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Redis\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Trait\ResponseMsg;

class HomeProfitController extends AbstractController
{
    use ResponseMsg;

    protected Redis $redis;
    protected Normal $normal;

    #[Inject]
    protected Distributors $distributors;

    #[Inject]
    protected DistributorDevice $distributorDevice;

    #[Inject]
    protected Bill $bill;

    public function __construct()
    {
        $this->redis = container()->get(Redis::class);
        $this->normal = container()->get(Normal::class);
    }

    /**盈利额
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getProfit(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $today = date('Y-m-d', time());
        $class_id = $request->input('class_id', 0);
        if ($class_id > 0) {
            $stations = Station::where('class_id', $class_id)->pluck('id')->toArray();
            if(count($stations) > 0){
                $orders = Order::whereIn('station_id', $stations)
                    ->where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('status', Order::STATUS_END)
                    ->pluck('id')->toArray();
                $data['today'] = $this->bill
                    ->where('account_type', 'App\Model\Distributors')
                    ->whereIn('target_id', $orders)
                    ->where('type', $this->bill::TYPE_ORDER_PAY)
                    ->sum('fee');
                $allOrders = Order::whereIn('station_id', $stations)
                    ->where('status', Order::STATUS_END)
                    ->pluck('id')->toArray();
                $data['all'] = $this->bill
                    ->where('account_type', 'App\Model\Distributors')
                    ->whereIn('target_id', $allOrders)
                    ->where('type', $this->bill::TYPE_ORDER_PAY)
                    ->sum('fee');
            }else{
                $data['today'] = 0;
                $data['all'] = 0;
            }
        } else {
            $data['all'] = $this->distributorDevice->where('distributor_id', $info['id'])
                ->sum('profit');
            $data['today'] = $this->bill
                ->where('created_at', '>=', $today . ' 00:00:00')
                ->where('created_at', '<=', $today . ' 23:59:59')
                ->where('account_type', 'App\Model\Distributors')
                ->where('account_id', $info['id'])
                ->where('type', $this->bill::TYPE_ORDER_PAY)
                ->sum('fee');
        }
        return $this->success($data);
    }

    public function insideProfit(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $class_id = $request->input('class_id', 0);
        if ($class_id > 0) {
            $stations = Station::where('class_id', $class_id)->pluck('id')->toArray();
            if(count($stations) > 0){
                $devices = Device::whereIn('station_id', $stations)
                    ->get(['id']);
            }else{
                $devices =[];
            }
        } else {
            if ($info['level'] == 1) {
                $devices = Device::where('distributor_id', $info['id'])
                    ->get(['id']);
            } else {
                $devices = Device::where('child_distributor_id', $info['id'])
                    ->get(['id']);
            }
        }
        $indDevices = [];
        foreach ($devices as $v) {
            $indDevices[] = $v['id'];
        }
        $params = $request->inputs(['start', 'end']);
        $status = [Order::STATUS_END, Order::STATUS_REFUNDED];
        if (array_key_exists('start', $params) && $params['start']) {
            if ($info['level'] == 1) {
                $todayPower = Order::where('stop_at', '>=', $params['start'] . ' 00:00:00')
                    ->where('stop_at', '<=', $params['end'] . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->whereIn('status', $status)
                    ->where('is_disabled', 0)
                    ->sum('power_fee');
                $data['today_income'] = $todayPower;
                $todayReturn = Order::where('stop_at', '>=', $params['start'] . ' 00:00:00')
                    ->where('stop_at', '<=', $params['end'] . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->where('is_return_fee', 1)
                    ->where('is_disabled', 0)
                    ->sum('return_fee');
                $data['today_refund'] = $todayReturn;
                $data['today'] = sprintf("%.2f", $todayPower - $todayReturn);
            } else {
                $todayPower = Order::where('stop_at', '>=', $params['start'] . ' 00:00:00')
                    ->where('stop_at', '<=', $params['end'] . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->whereIn('status', $status)
                    ->sum('power_fee');
                $data['today_income'] = $todayPower;
                $todayReturn = Order::where('stop_at', '>=', $params['start'] . ' 00:00:00')
                    ->where('stop_at', '<=', $params['end'] . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->where('is_return_fee', 1)
                    ->sum('return_fee');
                $data['today_refund'] = $todayReturn;
                $data['today'] = sprintf("%.2f", $todayPower - $todayReturn);
            }
        } else {
            $today = date('Y-m-d', time());
            if ($info['level'] == 1) {
                $todayPower = Order::where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->whereIn('status', $status)
                    ->where('is_disabled', 0)
                    ->sum('power_fee');
                $data['today_income'] = $todayPower;
                $todayReturn = Order::where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->where('is_return_fee', 1)
                    ->where('is_disabled', 0)
                    ->sum('return_fee');
                $data['today_refund'] = $todayReturn;
                $data['today'] = sprintf("%.2f", $todayPower - $todayReturn);
            } else {
                $todayPower = Order::where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->whereIn('status', $status)
                    ->sum('power_fee');
                $data['today_income'] = $todayPower;
                $todayReturn = Order::where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->whereIn('device_id', $indDevices)
                    ->where('is_return_fee', 1)
                    ->sum('return_fee');
                $data['today_refund'] = $todayReturn;
                $data['today'] = sprintf("%.2f", $todayPower - $todayReturn);
            }
        }
        return $this->success($data);
    }

    /**营业额
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function orderProfit(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $class_id = $request->input('class_id', 0);
        if ($class_id > 0) {
            $stations = Station::where('class_id', $class_id)->pluck('id')->toArray();
            $status = [Order::STATUS_END, Order::STATUS_REFUNDED];
            $powerFee = Order::whereIn('station_id', $stations)
                ->whereIn('status', $status)
                ->where('is_draw', 0)
                ->sum('power_fee');
            $returnFee = Order::whereIn('station_id', $stations)
                ->where('is_return_fee', 1)
                ->where('is_draw', 0)
                ->sum('return_fee');
            $data['all'] = sprintf("%.2f", $powerFee - $returnFee);
            $today = date('Y-m-d', time());
            $data['today_count'] = Order::where('stop_at', '>=', $today . ' 00:00:00')
                ->where('stop_at', '<=', $today . ' 23:59:59')
                ->where('is_draw', 0)
                ->whereIn('station_id', $stations)
                ->whereIn('status', $status)
                ->count();
            $todayPower = Order::where('stop_at', '>=', $today . ' 00:00:00')
                ->where('stop_at', '<=', $today . ' 23:59:59')
                ->where('is_draw', 0)
                ->whereIn('station_id', $stations)
                ->whereIn('status', $status)
                ->sum('power_fee');
            $data['today_income'] = $todayPower;
            $todayReturn = Order::where('stop_at', '>=', $today . ' 00:00:00')
                ->where('stop_at', '<=', $today . ' 23:59:59')
                ->where('is_draw', 0)
                ->whereIn('station_id', $stations)
                ->where('is_return_fee', 1)
                ->sum('return_fee');
            $data['today_refund'] = $todayReturn;
            $data['today'] = sprintf("%.2f", $todayPower - $todayReturn);
        } else {
            if (true) {
                $today = date('Y-m-d', time());
                $countKey = 'DISTRIBUTOR_ORDER_COUNT' . $today . '_' . $info['id'];
                $powerKey = 'DISTRIBUTOR_ORDER_POWER_' . $info['id'];
                $returnKey = 'DISTRIBUTOR_ORDER_RETURN_' . $info['id'];
                $todayPower = 'DISTRIBUTOR_ORDER_POWER_' . date('Y-m-d', time()) . '_' . $info['id'];
                $todayReturn = 'DISTRIBUTOR_ORDER_RETURN_' . date('Y-m-d', time()) . '_' . $info['id'];
                $status = [Order::STATUS_END, Order::STATUS_REFUNDED];
                if (!redis()->exists($powerKey)) {
                    if ($info['level'] == 1) {
                        $devices = Device::where('distributor_id', $info['id'])
                            ->get(['id']);
                    } else {
                        $devices = Device::where('child_distributor_id', $info['id'])
                            ->get(['id']);
                    }
                    $indDevices = [];
                    foreach ($devices as $v) {
                        $indDevices[] = $v['id'];
                    }
                    $powerFee = Order::whereIn('device_id', $indDevices)
                        ->whereIn('status', $status)
                        ->where('is_draw', 0)
                        ->where('is_disabled', 0)
                        ->sum('power_fee');
                    redis()->set($powerKey, $powerFee);
                    $returnFee = Order::whereIn('device_id', $indDevices)
                        ->where('is_return_fee', 1)
                        ->where('is_draw', 0)
                        ->where('is_disabled', 0)
                        ->sum('return_fee');
                    redis()->set($returnKey, $returnFee);
                } else {
                    $powerFee = redis()->get($powerKey);
                    $returnFee = redis()->get($returnKey);
                }
                $data['all'] = sprintf("%.2f", $powerFee - $returnFee);
                if (redis()->exists($countKey)) {
                    $data['today_count'] = redis()->get($countKey);
                } else {
                    $data['today_count'] = 0;
                }
                if (redis()->exists($todayPower)) {
                    $data['today_income'] = redis()->get($todayPower);
                    $data['today_refund'] = redis()->get($todayReturn);
                    $data['today'] = sprintf("%.2f", $data['today_income'] - $data['today_refund']);
                } else {
                    $data['today_refund'] = $data['today_income'] = $data['today'] = sprintf("%.2f", 0);
                }
            } else {
                $status = [Order::STATUS_END, Order::STATUS_REFUNDED];
                $powerFee = Order::where('distributor_id', $info['id'])
                    ->whereIn('status', $status)
                    ->where('is_draw', 0)
                    ->sum('power_fee');
                $returnFee = Order::where('distributor_id', $info['id'])
                    ->where('is_return_fee', 1)
                    ->where('is_draw', 0)
                    ->sum('return_fee');
                $data['all'] = sprintf("%.2f", $powerFee - $returnFee);
                $today = date('Y-m-d', time());
                $data['today_count'] = Order::where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->where('distributor_id', $info['id'])
                    ->whereIn('status', $status)
                    ->count();
                $todayPower = Order::where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->where('distributor_id', $info['id'])
                    ->whereIn('status', $status)
                    ->sum('power_fee');
                $data['today_income'] = $todayPower;
                $todayReturn = Order::where('stop_at', '>=', $today . ' 00:00:00')
                    ->where('stop_at', '<=', $today . ' 23:59:59')
                    ->where('is_draw', 0)
                    ->where('distributor_id', $info['id'])
                    ->where('is_return_fee', 1)
                    ->sum('return_fee');
                $data['today_refund'] = $todayReturn;
                $data['today'] = sprintf("%.2f", $todayPower - $todayReturn);
            }
        }
        $data['rate'] = $this->distributors->where('id', $info['id'])->value('rate');
        return $this->success($data);
    }

    /**折线图数据
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getCharts(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $endDate = Carbon::now();  // 当前日期时间
        $startDate = $endDate->copy()->subDays(14);  // 最近十五天的起始日期
        $dates = [];
        $data = [];
        while ($startDate->lte($endDate)) {
            $nowDay = $startDate->toDateString();
            $dates[] = $nowDay;
            $data['date'][] = date('m/d', strtotime($nowDay));
            $startDate->addDay();
        }
        $class_id = $request->input('class_id', 0);
        if ($class_id > 0) {
            $stations = Station::where('class_id', $class_id)->pluck('id')->toArray();
            foreach ($dates as $k => $v) {
                $orders = Order::whereIn('station_id', $stations)
                    ->where('stop_at', '>=', $v . ' 00:00:00')
                    ->where('stop_at', '<=', $v . ' 23:59:59')
                    ->where('status', Order::STATUS_END)
                    ->pluck('id')->toArray();
                $data['list'][] = $this->bill
                    ->where('created_at', '>=', $v . ' 00:00:00')
                    ->where('created_at', '<=', $v . ' 23:59:59')
                    ->where('account_type', 'App\Model\Distributors')
                    ->whereIn('target_id', $orders)
                    ->where('type', $this->bill::TYPE_ORDER_PAY)
                    ->sum('fee');
            }
        } else {
            foreach ($dates as $k => $v) {
                $data['list'][] = $this->bill
                    ->where('created_at', '>=', $v . ' 00:00:00')
                    ->where('created_at', '<=', $v . ' 23:59:59')
                    ->where('account_type', 'App\Model\Distributors')
                    ->where('account_id', $info['id'])
                    ->where('type', $this->bill::TYPE_ORDER_PAY)
                    ->sum('fee');
            }
        }
        return $this->success($data);
    }

    /**营业额折线图
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function orderCharts(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $class_id = $request->input('class_id', 0);
        if ($class_id > 0) {
            $stations = Station::where('class_id', $class_id)->pluck('id')->toArray();
            $devices = Device::whereIn('station_id', $stations)
                ->get(['id']);
        } else {
            if ($info['level'] == 1) {
                $devices = Device::where('distributor_id', $info['id'])
                    ->get(['id']);
            } else {
                $devices = Device::where('child_distributor_id', $info['id'])
                    ->get(['id']);
            }
        }
        $indDevices = [];
        foreach ($devices as $v) {
            $indDevices[] = $v['id'];
        }
        $status = [Order::STATUS_END, Order::STATUS_REFUNDED];
        $endDate = Carbon::now();  // 当前日期时间
        $startDate = $endDate->copy()->subDays(14);  // 最近十五天的起始日期
        $dates = [];
        $data = [];
        while ($startDate->lte($endDate)) {
            $nowDay = $startDate->toDateString();
            $dates[] = $nowDay;
            $data['date'][] = date('m/d', strtotime($nowDay));
            $startDate->addDay();
        }
        foreach ($dates as $k => $v) {
            $powerFee = Order::where('created_at', '>=', $v . ' 00:00:00')
                ->where('created_at', '<=', $v . ' 23:59:59')
                ->whereIn('device_id', $indDevices)
                ->where('is_draw', 0)
                ->where('is_disabled', 0)
                ->whereIn('status', $status)
                ->sum('power_fee');
            $returnFee = Order::where('created_at', '>=', $v . ' 00:00:00')
                ->where('created_at', '<=', $v . ' 23:59:59')
                ->whereIn('device_id', $indDevices)
                ->where('is_return_fee', 1)
                ->where('is_draw', 0)
                ->where('is_disabled', 0)
                ->sum('return_fee');
            $data['list'][] = sprintf("%.2f", $powerFee - $returnFee);
        }

        return $this->success($data);
    }

}
